import { app, BrowserWindow, ipcMain, dialog } from 'electron'
import { join } from 'path'
import { readFile, writeFile, mkdirSync, existsSync } from 'fs'
import { dirname, basename, extname, join as pathJoin } from 'path'
import { promisify } from 'util'
import Store from 'electron-store'
import { LangChainService } from './services/LangChainService'
import { FileWatcherService } from './services/FileWatcherService'
import { ShortcutService } from './services/ShortcutService'
import { GitService } from './services/GitService'
import { setupGitHandlers } from './handlers/gitHandlers'
import { AIStreamOptions } from './services/AIProviderAdapter'
import { log } from './utils/Logger'

const readFileAsync = promisify(readFile)
const writeFileAsync = promisify(writeFile)

// Initialize electron-store for settings and recent files
const store = new Store()

class IntelliMarkApp {
  private mainWindow: BrowserWindow | null = null
  private langChainService: LangChainService
  private fileWatcherService: FileWatcherService
  private shortcutService: ShortcutService | null = null
  private gitService: GitService

  constructor() {
    this.langChainService = new LangChainService()
    this.fileWatcherService = new FileWatcherService()
    this.gitService = new GitService()
    // shortcutService will be initialized after window creation
  }

  private createWindow(): void {
    this.mainWindow = new BrowserWindow({
      width: 1400,
      height: 900,
      minWidth: 1000,
      minHeight: 600,
      titleBarStyle: 'hiddenInset',
      show: false,
      webPreferences: {
        preload: join(__dirname, '../preload/preload.js'),
        contextIsolation: true,
        nodeIntegration: false,
        webSecurity: true
      }
    })

    // Show window when ready to prevent visual flash
    this.mainWindow.once('ready-to-show', () => {
      this.mainWindow?.show()
    })

    if (process.env.NODE_ENV === 'development') {
      this.mainWindow.loadURL('http://localhost:5173')
      this.mainWindow.webContents.openDevTools()
    } else {
      this.mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
    }

    // Handle window closed
    this.mainWindow.on('closed', () => {
      this.cleanup()
      this.mainWindow = null
    })

    // Initialize services that require the window
    this.shortcutService = new ShortcutService(this.mainWindow)
    this.setupServiceEvents()
  }

  private setupIpcHandlers(): void {
    // File operations
    this.setupFileHandlers()

    // AI operations (placeholder for now)
    this.setupAIHandlers()

    // Settings handlers
    this.setupSettingsHandlers()

    // Dialog handlers
    this.setupDialogHandlers()

    // Theme handlers
    this.setupThemeHandlers()

    // Window handlers
    this.setupWindowHandlers()

    // Git handlers
    setupGitHandlers()
  }

  private setupFileHandlers(): void {
    // Open file
    ipcMain.handle('file:open', async (_, filePath?: string) => {
      try {
        let targetPath = filePath

        if (!targetPath) {
          const result = await dialog.showOpenDialog(this.mainWindow!, {
            title: '打开 Markdown 文件',
            filters: [
              { name: 'Markdown Files', extensions: ['md', 'markdown'] },
              { name: 'All Files', extensions: ['*'] }
            ],
            properties: ['openFile']
          })

          if (result.canceled) {
            return null
          }

          targetPath = result.filePaths[0]
        }

        const content = await readFileAsync(targetPath, 'utf-8')
        this.addToRecentFiles(targetPath)

        return { path: targetPath, content }
      } catch (error) {
        log.error('Failed to open file:', error, 'FileSystem')
        throw new Error(`无法打开文件: ${error instanceof Error ? error.message : '未知错误'}`)
      }
    })

    // Save file
    ipcMain.handle('file:save', async (_, content: string, filePath?: string) => {
      try {
        let targetPath = filePath

        if (!targetPath) {
          const result = await dialog.showSaveDialog(this.mainWindow!, {
            title: '保存 Markdown 文件',
            filters: [
              { name: 'Markdown Files', extensions: ['md'] },
              { name: 'All Files', extensions: ['*'] }
            ],
            defaultPath: '未命名文档.md'
          })

          if (result.canceled) {
            return null
          }

          targetPath = result.filePath!
        }

        await writeFileAsync(targetPath, content, 'utf-8')
        this.addToRecentFiles(targetPath)

        return targetPath
      } catch (error) {
        log.error('Failed to save file:', error, 'FileSystem')
        throw new Error(`无法保存文件: ${error instanceof Error ? error.message : '未知错误'}`)
      }
    })

    // Save file as
    ipcMain.handle('file:save-as', async (_, content: string) => {
      try {
        const result = await dialog.showSaveDialog(this.mainWindow!, {
          title: '另存为',
          filters: [
            { name: 'Markdown Files', extensions: ['md'] },
            { name: 'All Files', extensions: ['*'] }
          ],
          defaultPath: '未命名文档.md'
        })

        if (result.canceled) {
          return null
        }

        const targetPath = result.filePath!
        await writeFileAsync(targetPath, content, 'utf-8')
        this.addToRecentFiles(targetPath)

        return targetPath
      } catch (error) {
        console.error('Failed to save file as:', error)
        throw new Error(`无法另存为: ${error instanceof Error ? error.message : '未知错误'}`)
      }
    })

    // Get recent files
    ipcMain.handle('file:get-recent', () => {
      const recentFiles = store.get('recentFiles', []) as Array<{
        path: string
        openedTime: number
        modifiedTime: number
      }>
      
      // 按打开时间从近到远排序
      return recentFiles.sort((a, b) => b.openedTime - a.openedTime)
    })

    // Handle image upload
    ipcMain.handle('file:handle-image-upload', async (_, data: { imageData: string; fileName: string; docPath: string }) => {
      try {
        const { imageData, fileName, docPath } = data

        // If no doc path, save to temp directory
        let assetsDir: string
        if (docPath) {
          const docDir = dirname(docPath)
          assetsDir = pathJoin(docDir, 'assets')
        } else {
          assetsDir = pathJoin(app.getPath('temp'), 'intellimark-assets')
        }

        // Create assets directory if it doesn't exist
        if (!existsSync(assetsDir)) {
          mkdirSync(assetsDir, { recursive: true })
        }

        // Generate unique filename
        const timestamp = Date.now()
        const ext = extname(fileName) || '.png'
        const uniqueFileName = `${basename(fileName, ext)}-${timestamp}${ext}`
        const imagePath = pathJoin(assetsDir, uniqueFileName)

        // Convert base64 to buffer and save
        const base64Data = imageData.replace(/^data:image\/\w+;base64,/, '')
        const buffer = Buffer.from(base64Data, 'base64')
        await writeFileAsync(imagePath, buffer)

        // Return relative path
        const relativePath = docPath ? `./assets/${uniqueFileName}` : imagePath
        return relativePath
      } catch (error) {
        console.error('Failed to handle image upload:', error)
        throw new Error(`无法处理图片上传: ${error instanceof Error ? error.message : '未知错误'}`)
      }
    })
  }

  private setupAIHandlers(): void {
    // AI invoke handler with real LangChain integration
    ipcMain.handle('ai:invoke', async (_, { action, text, options }) => {
      try {
        log.ai(`AI Action: ${action}`, { text, options })

        // Check if AI service is configured
        if (!this.langChainService.isConfigured()) {
          throw new Error('AI 服务未配置，请在设置中配置 API 密钥')
        }

        // Get settings for retry configuration
        const settings = store.get('settings', {}) as any
        const aiConfig = settings.ai || {}
        const maxRetries = aiConfig.retryAttempts ?? 3
        const retryDelay = aiConfig.retryDelay ?? 1000

        let lastError: Error | undefined

        for (let attempt = 0; attempt <= maxRetries; attempt++) {
          try {
            let result: string

            switch (action) {
              case 'polish':
                result = await this.langChainService.polish(text)
                break
              case 'shorten':
                result = await this.langChainService.shorten(text)
                break
              case 'expand':
                result = await this.langChainService.expand(text)
                break
              case 'translate':
                result = await this.langChainService.translate(text, options?.targetLang || 'English')
                break
              case 'fix-grammar':
                result = await this.langChainService.fixGrammar(text)
                break
              case 'change-tone':
                result = await this.langChainService.changeTone(text, options?.tone || 'professional')
                break
              case 'summarize':
                result = await this.langChainService.summarize(text)
                break
              case 'continue-writing':
                result = await this.langChainService.continueWriting(text, options?.context || '')
                break
              default:
                throw new Error(`不支持的 AI 操作: ${action}`)
            }

            return result
          } catch (error) {
            lastError = error as Error

            // Don't retry on configuration errors
            if (lastError.message.includes('API key') ||
                lastError.message.includes('configuration') ||
                lastError.message.includes('invalid')) {
              throw lastError
            }

            // Wait before retry (except on last attempt)
            if (attempt < maxRetries) {
              await new Promise(resolve => setTimeout(resolve, retryDelay))
            }
          }
        }

        throw lastError!

      } catch (error) {
        log.error('AI action failed:', error, 'AI')
        throw new Error(`AI 操作失败: ${error instanceof Error ? error.message : '未知错误'}`)
      }
    })

    // AI streaming support with enhanced error handling
    ipcMain.handle('ai:stream', async (_, { action, text, options, requestId }) => {
      try {
        if (!this.langChainService.isConfigured()) {
          throw new Error('AI 服务未配置')
        }

        log.ai(`Starting AI stream: ${action}`, { text, options, requestId })

        const stream = this.langChainService.streamAIAction(action, { text, ...options }, {
          onProgress: (chunk: string) => {
            this.mainWindow?.webContents.send('ai:stream-chunk', {
              requestId,
              chunk,
              action
            })
          },
          onError: (error: Error) => {
            this.mainWindow?.webContents.send('ai:stream-error', {
              requestId,
              error: error.message,
              action
            })
          },
          onComplete: (result: string) => {
            this.mainWindow?.webContents.send('ai:stream-end', {
              requestId,
              result,
              action
            })
          }
        } as AIStreamOptions)

        for await (const chunk of stream) {
          // Send chunk through webContents
          this.mainWindow?.webContents.send('ai:stream-chunk', {
            requestId,
            chunk,
            action
          })
        }

        // Send completion event
        this.mainWindow?.webContents.send('ai:stream-end', {
          requestId,
          action
        })

      } catch (error) {
        log.error('AI streaming failed:', error, 'AI')
        this.mainWindow?.webContents.send('ai:stream-error', {
          requestId,
          error: error instanceof Error ? error.message : '未知错误',
          action
        })
      }
    })

    // AI configuration handlers
    ipcMain.handle('ai:get-config', () => {
      return this.langChainService.getConfig()
    })

    ipcMain.handle('ai:update-config', async (_, config) => {
      await this.langChainService.updateConfig(config)
      return this.langChainService.getConfig()
    })

    ipcMain.handle('ai:test-connection', async () => {
      return await this.langChainService.testConnection()
    })

    ipcMain.handle('ai:get-available-models', () => {
      return this.langChainService.getAvailableModels()
    })

    // Additional AI handlers for enhanced functionality
    ipcMain.handle('ai:get-supported-providers', () => {
      const { LangChainService } = require('./services/LangChainService')
      return LangChainService.getSupportedProviders()
    })

    ipcMain.handle('ai:health-check', async () => {
      return await this.langChainService.healthCheck()
    })

    ipcMain.handle('ai:validate-config', async (event, config: any) => {
      try {
        const validation = {
          valid: true,
          error: ''
        }

        // Validate required fields
        if (!config.provider) {
          validation.valid = false
          validation.error = 'AI provider is required'
          return validation
        }

        if (!config.apiKey && config.provider !== 'local') {
          validation.valid = false
          validation.error = 'API key is required for cloud providers'
          return validation
        }

        // Validate provider-specific settings
        if (config.provider === 'openai' && !config.model) {
          validation.valid = false
          validation.error = 'Model selection is required for OpenAI'
          return validation
        }

        if (config.provider === 'anthropic' && !config.model) {
          validation.valid = false
          validation.error = 'Model selection is required for Anthropic'
          return validation
        }

        // Validate numeric settings
        if (config.temperature !== undefined) {
          if (config.temperature < 0 || config.temperature > 2) {
            validation.valid = false
            validation.error = 'Temperature must be between 0 and 2'
            return validation
          }
        }

        if (config.maxTokens !== undefined) {
          if (config.maxTokens < 1 || config.maxTokens > 32000) {
            validation.valid = false
            validation.error = 'Max tokens must be between 1 and 32000'
            return validation
          }
        }

        // Validate timeout
        if (config.timeout !== undefined) {
          if (config.timeout < 1000 || config.timeout > 120000) {
            validation.valid = false
            validation.error = 'Timeout must be between 1000ms and 120000ms'
            return validation
          }
        }

        // Validate retry settings
        if (config.retryAttempts !== undefined) {
          if (config.retryAttempts < 0 || config.retryAttempts > 5) {
            validation.valid = false
            validation.error = 'Retry attempts must be between 0 and 5'
            return validation
          }
        }

        if (config.retryDelay !== undefined) {
          if (config.retryDelay < 100 || config.retryDelay > 10000) {
            validation.valid = false
            validation.error = 'Retry delay must be between 100ms and 10000ms'
            return validation
          }
        }

        return validation
      } catch (error) {
        log.error('AI config validation error:', error, 'AI')
        return {
          valid: false,
          error: error instanceof Error ? error.message : 'Validation failed'
        }
      }
    })

    // Direct chat completion handler for advanced use cases
    ipcMain.handle('ai:chat', async (_, { messages, options }) => {
      try {
        if (!this.langChainService.isConfigured()) {
          throw new Error('AI 服务未配置')
        }

        const result = await this.langChainService.chatCompletion(messages, options)
        return result
      } catch (error) {
        console.error('AI chat failed:', error)
        throw new Error(`AI 聊天失败: ${error instanceof Error ? error.message : '未知错误'}`)
      }
    })

    // Streaming chat completion
    ipcMain.handle('ai:stream-chat', async (_, { messages, options, requestId }) => {
      try {
        if (!this.langChainService.isConfigured()) {
          throw new Error('AI 服务未配置')
        }

        const stream = this.langChainService.streamChatCompletion(messages, {
          ...options,
          onProgress: (chunk: string) => {
            this.mainWindow?.webContents.send('ai:chat-chunk', {
              requestId,
              chunk
            })
          },
          onError: (error: Error) => {
            this.mainWindow?.webContents.send('ai:chat-error', {
              requestId,
              error: error.message
            })
          },
          onComplete: (result: string) => {
            this.mainWindow?.webContents.send('ai:chat-end', {
              requestId,
              result
            })
          }
        } as AIStreamOptions)

        for await (const chunk of stream) {
          this.mainWindow?.webContents.send('ai:chat-chunk', {
            requestId,
            chunk
          })
        }

        this.mainWindow?.webContents.send('ai:chat-end', {
          requestId
        })

      } catch (error) {
        console.error('AI chat streaming failed:', error)
        this.mainWindow?.webContents.send('ai:chat-error', {
          requestId,
          error: error instanceof Error ? error.message : '未知错误'
        })
      }
    })
  }

  private setupSettingsHandlers(): void {
    ipcMain.handle('settings:get', () => {
      return store.store
    })

    ipcMain.handle('settings:update', (_, settings: any) => {
      store.set(settings)
      return store.store
    })
  }

  private setupDialogHandlers(): void {
    ipcMain.handle('dialog:show-open', async () => {
      const result = await dialog.showOpenDialog(this.mainWindow!, {
        title: '打开文件',
        filters: [
          { name: 'Markdown Files', extensions: ['md', 'markdown'] },
          { name: 'All Files', extensions: ['*'] }
        ],
        properties: ['openFile']
      })

      return result
    })

    ipcMain.handle('dialog:show-save', async () => {
      const result = await dialog.showSaveDialog(this.mainWindow!, {
        title: '保存文件',
        filters: [
          { name: 'Markdown Files', extensions: ['md'] },
          { name: 'All Files', extensions: ['*'] }
        ]
      })

      return result
    })

    ipcMain.handle('dialog:show-input', async (_, options: { title: string; default?: string }) => {
      try {
        // For now, we'll create a simple workaround using a save dialog with a default name
        // In a real implementation, you might want to create a custom HTML dialog or use a library
        const result = await dialog.showSaveDialog(this.mainWindow!, {
          title: options.title || '输入文件名',
          defaultPath: options.default || 'untitled.md',
          filters: [
            { name: 'Markdown Files', extensions: ['md'] },
            { name: 'All Files', extensions: ['*'] }
          ]
        })

        if (result.canceled || !result.filePath) {
          return { canceled: true }
        }

        // Extract just the filename from the path
        const path = require('path')
        const fileName = path.basename(result.filePath)
        return { canceled: false, value: fileName }
      } catch (error) {
        console.error('Failed to show input dialog:', error)
        return { canceled: true }
      }
    })
  }

  private setupThemeHandlers(): void {
    ipcMain.handle('theme:set', (_, theme: 'light' | 'dark' | 'auto') => {
      store.set('theme', theme)
      return theme
    })

    ipcMain.handle('theme:get', () => {
      return store.get('theme', 'system') as string
    })
  }

  private setupWindowHandlers(): void {
    ipcMain.handle('window:minimize', () => {
      this.mainWindow?.minimize()
    })

    ipcMain.handle('window:maximize', () => {
      if (this.mainWindow?.isMaximized()) {
        this.mainWindow.unmaximize()
      } else {
        this.mainWindow?.maximize()
      }
    })

    ipcMain.handle('window:close', () => {
      this.mainWindow?.close()
    })
  }

  private setupGitHandlers(): void {
    // Initialize git repository
    ipcMain.handle('git:init', async (_, repoPath: string) => {
      try {
        return await this.gitService.initRepository(repoPath)
      } catch (error) {
        console.error('Failed to initialize git repository:', error)
        throw new Error(`无法初始化Git仓库: ${error instanceof Error ? error.message : '未知错误'}`)
      }
    })

    // Get git status
    ipcMain.handle('git:status', async (_, repoPath: string) => {
      try {
        return await this.gitService.getStatus(repoPath)
      } catch (error) {
        console.error('Failed to get git status:', error)
        throw new Error(`无法获取Git状态: ${error instanceof Error ? error.message : '未知错误'}`)
      }
    })

    // Add files to git
    ipcMain.handle('git:add', async (_, repoPath: string, files: string[]) => {
      try {
        return await this.gitService.addFiles(repoPath, files)
      } catch (error) {
        console.error('Failed to add files to git:', error)
        throw new Error(`无法添加文件到Git: ${error instanceof Error ? error.message : '未知错误'}`)
      }
    })

    // Commit changes
    ipcMain.handle('git:commit', async (_, repoPath: string, message: string) => {
      try {
        return await this.gitService.commit(repoPath, message)
      } catch (error) {
        console.error('Failed to commit changes:', error)
        throw new Error(`无法提交更改: ${error instanceof Error ? error.message : '未知错误'}`)
      }
    })

    // Get commit history
    ipcMain.handle('git:log', async (_, repoPath: string, limit?: number) => {
      try {
        return await this.gitService.getCommitHistory(repoPath, limit)
      } catch (error) {
        console.error('Failed to get commit history:', error)
        throw new Error(`无法获取提交历史: ${error instanceof Error ? error.message : '未知错误'}`)
      }
    })

    // Create branch
    ipcMain.handle('git:branch', async (_, repoPath: string, branchName: string) => {
      try {
        return await this.gitService.createBranch(repoPath, branchName)
      } catch (error) {
        console.error('Failed to create branch:', error)
        throw new Error(`无法创建分支: ${error instanceof Error ? error.message : '未知错误'}`)
      }
    })

    // Switch branch
    ipcMain.handle('git:checkout', async (_, repoPath: string, branchName: string) => {
      try {
        return await this.gitService.switchBranch(repoPath, branchName)
      } catch (error) {
        console.error('Failed to switch branch:', error)
        throw new Error(`无法切换分支: ${error instanceof Error ? error.message : '未知错误'}`)
      }
    })

    // Get current branch
    ipcMain.handle('git:current-branch', async (_, repoPath: string) => {
      try {
        return await this.gitService.getCurrentBranch(repoPath)
      } catch (error) {
        console.error('Failed to get current branch:', error)
        throw new Error(`无法获取当前分支: ${error instanceof Error ? error.message : '未知错误'}`)
      }
    })

    // Get remote branches
    ipcMain.handle('git:remote-branches', async (_, repoPath: string) => {
      try {
        return await this.gitService.getRemoteBranches(repoPath)
      } catch (error) {
        console.error('Failed to get remote branches:', error)
        throw new Error(`无法获取远程分支: ${error instanceof Error ? error.message : '未知错误'}`)
      }
    })

    // Pull changes
    ipcMain.handle('git:pull', async (_, repoPath: string, remote?: string, branch?: string) => {
      try {
        return await this.gitService.pull(repoPath, remote, branch)
      } catch (error) {
        console.error('Failed to pull changes:', error)
        throw new Error(`无法拉取更改: ${error instanceof Error ? error.message : '未知错误'}`)
      }
    })

    // Push changes
    ipcMain.handle('git:push', async (_, repoPath: string, remote?: string, branch?: string) => {
      try {
        return await this.gitService.push(repoPath, remote, branch)
      } catch (error) {
        console.error('Failed to push changes:', error)
        throw new Error(`无法推送更改: ${error instanceof Error ? error.message : '未知错误'}`)
      }
    })

    // Clone repository
    ipcMain.handle('git:clone', async (_, url: string, targetPath: string) => {
      try {
        return await this.gitService.clone(url, targetPath)
      } catch (error) {
        console.error('Failed to clone repository:', error)
        throw new Error(`无法克隆仓库: ${error instanceof Error ? error.message : '未知错误'}`)
      }
    })

    // Check if path is a git repository
    ipcMain.handle('git:is-repo', async (_, repoPath: string) => {
      try {
        return await this.gitService.isRepository(repoPath)
      } catch (error) {
        console.error('Failed to check if repository:', error)
        return false
      }
    })
  }

  private addToRecentFiles(filePath: string): void {
    // 获取文件修改时间
    const fs = require('fs')
    const stats = fs.statSync(filePath)
    const modifiedTime = stats.mtime.getTime()
    const openedTime = Date.now()
    
    // 获取当前最近文件列表
    const recentFiles = (store.get('recentFiles', []) as Array<{
      path: string
      openedTime: number
      modifiedTime: number
    }>)
    
    // 过滤掉相同路径的文件
    const filteredFiles = recentFiles.filter(file => file.path !== filePath)
    
    // 添加新文件到列表开头
    const newFile = {
      path: filePath,
      openedTime: openedTime,
      modifiedTime: modifiedTime
    }
    
    // 限制列表长度为10
    const updatedFiles = [newFile, ...filteredFiles].slice(0, 10)
    
    // 保存更新后的列表
    store.set('recentFiles', updatedFiles)
  }

  private setupServiceEvents(): void {
    // File watcher events
    this.fileWatcherService.on('fileChanged', (event) => {
      this.mainWindow?.webContents.send('file:changed', event.path, event.content)
    })

    // Shortcut service events
    this.shortcutService?.on('newFile', () => {
      this.mainWindow?.webContents.send('file:new')
    })

    this.shortcutService?.on('openFile', () => {
      this.mainWindow?.webContents.send('file:open-dialog')
    })

    this.shortcutService?.on('saveFile', () => {
      this.mainWindow?.webContents.send('file:save')
    })

    this.shortcutService?.on('saveFileAs', () => {
      this.mainWindow?.webContents.send('file:save-as')
    })

    this.shortcutService?.on('globalNewNote', () => {
      // Show window if hidden and create new note
      if (this.mainWindow) {
        if (this.mainWindow.isMinimized()) {
          this.mainWindow.restore()
        }
        this.mainWindow.focus()
        this.mainWindow.webContents.send('file:new')
      }
    })

    this.shortcutService?.on('globalQuickOpen', () => {
      if (this.mainWindow) {
        if (this.mainWindow.isMinimized()) {
          this.mainWindow.restore()
        }
        this.mainWindow.focus()
        this.mainWindow.webContents.send('file:quick-open')
      }
    })
  }

  private cleanup(): void {
    // Cleanup all services
    this.fileWatcherService.dispose()
    this.shortcutService?.dispose()
    console.log('All services cleaned up')
  }

  public async start(): Promise<void> {
    await app.whenReady()

    // Set app user model id for Windows
    if (process.platform === 'win32') {
      app.setAppUserModelId('com.intellimark.app')
    }

    this.createWindow()
    this.setupIpcHandlers()

    app.on('window-all-closed', () => {
      if (process.platform !== 'darwin') {
        app.quit()
      }
    })

    app.on('activate', () => {
      if (BrowserWindow.getAllWindows().length === 0) {
        this.createWindow()
      }
    })
  }
}

// Global error handlers to prevent EPIPE errors
process.on('uncaughtException', (error) => {
  log.error('Uncaught Exception:', error, 'Global')
  // Don't exit the app, but log the error
})

process.on('unhandledRejection', (reason) => {
  log.error('Unhandled Rejection at:', reason, 'Global')
})

// Start the application
const intelliMarkApp = new IntelliMarkApp()
intelliMarkApp.start().catch(error => log.error('Application startup failed:', error, 'App'))
